package com.yyx.demo.config;


import com.yyx.demo.config.statement.MyHandler;
import com.yyx.demo.config.statement.StatementHandler;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * 读取与解析配置信息，并返回处理后的Environment
 */
public class MyConfiguration {

    private static  ClassLoader loader=ClassLoader.getSystemClassLoader();

    //初始化执行器
    public static StatementHandler newStatementHandler() {

        StatementHandler statementHandler = new MyHandler();
        return statementHandler;

    }

    /**
     * 读取xml信息并获取链接
     */
    public Connection build(String resource){
        try {
            InputStream stream=loader.getResourceAsStream(resource);
            SAXReader reader=new SAXReader();
            Document document=reader.read(stream);
            Element root =document.getRootElement();
            return evalDataSource(root);
        } catch (DocumentException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }

    private Connection evalDataSource(Element node) throws ClassNotFoundException {
        if (!node.getName().equals("database")){
            throw new RuntimeException("格式不对");
        }
        String driverClassName =null;
        String url =null;
        String username = null;
        String password = null;
        //获取属性节点
        for (Object item: node.elements("property")
             ) {
            Element i = (Element) item;
            String value = getValue(i);
            String name = i.attributeValue("name");
            if (name == null|| value==null){
                throw new RuntimeException("");
            }
            //赋值
            if ("url".equals(name)) {
                url = value;
            } else if ("username".equals(name)) {
                username = value;
            } else if ("password".equals(name)) {
                password = value;
            } else if ("driverClassName".equals(name)) {
                driverClassName = value;
            } else {
                throw new RuntimeException("[database]: <property> unknown name");
            }
        }
        //反射
        Class.forName(driverClassName);
        Connection connection=null;
        try {
            //建立数据库链接
            connection = DriverManager.getConnection(url,username,password);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return connection;
    }

    //获取property 属性的值 如果有value的值，没有设置value,则读取内容
    private String getValue(Element node) {
        return node.hasContent() ? node.getText() : node.attributeValue("value");
    }

    public MapperBean readMapper(String path) throws DocumentException {
        MapperBean mapper = new MapperBean();

        InputStream stream = loader.getResourceAsStream(path);
        SAXReader reader = new SAXReader();
        Document document = reader.read(stream);
        Element root = document.getRootElement();

        //把mapper 节点的nameSpace值存为接口名
        mapper.setInterfaceName(root.attributeValue("nameSpace").trim());

        List<Function> list = new ArrayList<Function>();// 用来存储方法的list
        for (Iterator rooIter= root.elementIterator(); rooIter.hasNext();) //遍历该根节点下所有子节点
        {
            Function fun = new Function(); //存储一条方法的信息
            Element e= (Element) rooIter.next();
            String sqltype = e.getName().trim();
            String funcName = e.attributeValue("id").trim();
            String sql = e.getText().trim();
            String resultType = e.attributeValue("resultType").trim();
            fun.setResultTypePath(resultType);
            fun.setSqltype(sqltype);
            fun.setFunName(funcName);

            Object newInstance = null;
            try {
                //获取那个实体类
                newInstance  = Class.forName(resultType).newInstance();
            } catch (IllegalAccessException e1) {
                e1.printStackTrace();
            } catch (InstantiationException e1) {
                e1.printStackTrace();
            } catch (ClassNotFoundException e1) {
                e1.printStackTrace();
            }

            fun.setResultType(newInstance);
            fun.setSql(sql);
            list.add(fun);
        }
        mapper.setList(list);

        return mapper;
    }

}
